﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace DateTimePickerControl
{
    public partial class DateTimePicker : UserControl, INotifyPropertyChanged
    {
        public DateTimePicker()
        {
            InitializeComponent();

            DatePickerObj.SelectedDate = DateTime.Now;
            this.SendPropertyChanged("SelectedDateTimeString");

            _selectedHour = DateTime.Now.Hour;
            _selectedMinute = DateTime.Now.Minute;
            _selectedSecond = DateTime.Now.Second;

            _oldTextBox = _currentTextBox = TextBox_Seconds;
            _currentTextBox.Background = Brushes.Pink;
        }
        public DateTime SelectedDateTime
        {
            get
            {
                DateTime obj;
                if (DatePickerObj != null)
                {
                    obj = DatePickerObj.SelectedDate ?? DateTime.Now;
                }
                else
                {
                    obj = DateTime.Now;
                }
                return obj.Add(new TimeSpan(SelectedHour - obj.Hour, SelectedMinute - obj.Minute, SelectedSecond - obj.Second));
            }
        }
        public String SelectedDateTimeString
        {
            get
            {
                return SelectedDateTime.ToString("yyyy-MM-dd HH-mm-ss");
            }
        }

        #region private methods
        private void TextBox_Hours_GotFocus(object sender, RoutedEventArgs e)
        {
            _oldTextBox.Background = Brushes.Transparent;
            _oldTextBox = _currentTextBox = TextBox_Hours;
            _currentTextBox.Background = Brushes.Pink;
        }
        private void TextBox_Minutes_GotFocus(object sender, RoutedEventArgs e)
        {
            _oldTextBox.Background = Brushes.Transparent;
            _oldTextBox = _currentTextBox = TextBox_Minutes;
            _currentTextBox.Background = Brushes.Pink;
        }
        private void TextBox_Seconds_GotFocus(object sender, RoutedEventArgs e)
        {
            _oldTextBox.Background = Brushes.Transparent;
            _oldTextBox = _currentTextBox = TextBox_Seconds;
            _currentTextBox.Background = Brushes.Pink;
        }
        private void ComboBox_DropDownClosed(object sender, EventArgs e)
        {
            this.SendPropertyChanged("SelectedDateTime");
            this.SendPropertyChanged("SelectedDateTimeString");
        }

        private void BTN_IncreaseTime_Click(object sender, RoutedEventArgs e)
        {
            Int32 result;
            if (Int32.TryParse(_currentTextBox.Text, out result))
            {
                result++;
                _currentTextBox.Text = result.ToString();
            }
        }
        private void BTN_DecrementTime_Click(object sender, RoutedEventArgs e)
        {
            Int32 result;
            if (Int32.TryParse(_currentTextBox.Text, out result))
            {
                result--;
                _currentTextBox.Text = result.ToString();
            }
        }
        
        #endregion

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        private void SendPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        #region private area
        public Int32 SelectedHour
        {
            get { return _selectedHour; }
            set
            {
                _selectedHour = value;
                SendPropertyChanged("SelectedHour");
            }
        }
        public Int32 SelectedMinute
        {
            get { return _selectedMinute; }
            set
            {
                _selectedMinute = value;
                SendPropertyChanged("SelectedMinute");
            }
        }
        public Int32 SelectedSecond
        {
            get { return _selectedSecond; }
            set
            {
                _selectedSecond = value;
                SendPropertyChanged("SelectedSecond");
            }
        }

        private TextBox _currentTextBox, _oldTextBox;
        private Int32 _selectedHour = DateTime.Now.Hour;
        private Int32 _selectedMinute = DateTime.Now.Minute;
        private Int32 _selectedSecond = DateTime.Now.Second;
        #endregion
    }
    public class Int32ToStringConverter : IValueConverter
    {
        object IValueConverter.Convert(object obj, Type type, object parameter, System.Globalization.CultureInfo culture)
        {
            return obj.ToString();
        }
        object IValueConverter.ConvertBack(object obj, Type type, object parameter, System.Globalization.CultureInfo culture)
        {
            return Int32.Parse((String)obj);
        }
    }
    public class TimeValidationRule:ValidationRule
    {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            Int32 iValue;
            if (Int32.TryParse((String)value, out iValue))
            {
                if (iValue < _minValue || iValue > _maxValue)
                    return new ValidationResult(false, "Out of range!");
                else
                    return new ValidationResult(true, null);
            }
            else
            {
                return new ValidationResult(false, null);
            }
        }

        public Int32 MinValue
        {
            get { return _minValue; }
            set { _minValue = value; }
        }
        public Int32 MaxValue
        {
            get { return _maxValue; }
            set { _maxValue = value; }
        }

        private Int32 _minValue = 0;
        private Int32 _maxValue = 59;
    }
}
